package com.douqu.game.core.entity.ext.data.challenge;

import com.bean.core.buffer.ByteBuffer;
import com.douqu.game.core.config.MailConfig;
import com.douqu.game.core.config.StableDataConfig;
import com.douqu.game.core.config.common.GoodsData;
import com.douqu.game.core.e.E_MailModelType;
import com.douqu.game.core.e.E_StableDataType;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.activity.MatchBaseInfo;
import com.douqu.game.core.entity.db.CardDB;
import com.douqu.game.core.entity.db.MailDB;
import com.douqu.game.core.entity.ext.MailInfo;
import com.douqu.game.core.entity.ext.data.BaseData;
import com.douqu.game.core.factory.ConfigFactory;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.util.CoreUtils;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Author: Bean
 * @Description:
 * @Date: 2018-03-13 18:18
 */
public class CampBattleData extends BaseData
{
    /** 当前活动ID */
    public String activityIndex = "";
    /** 已经报名次数 */
    public int applyCount;
    /** 复活次数(-1表示需要报名,不能用0来判断) */
    public int reviveCount = -1;
    /** 历史总胜利场次 */
    public int totalWinCount;
    /** 历史总战斗场次 */
    public int totalBattleCount;
    /** 历史最高连胜 */
    public int maxContinueWin;
    /** 历史累计功勋 */
    public int totalExploit;
    /** 历史最高排名 */
    public int maxRank;

    /**
     * 当天的奖励是否领取
     */
    private boolean isGetRewarded;

    /** 本次活动参战英雄 */
    private List<CardDB> battleCardList;
//    /** 本次活动匹配记录(只保存最近X次的,目前是2次) */
//    private List<String> matchList;
    /** 本次活动的战斗记录 */
    private List<CampBattleBean> battleList;
    /** 本次活动胜利次数(不用存数据库) */
    public int curWinCount;
    /** 本次活动总战斗场次(不用存数据库) */
    public int curBattleCount;
    /** 本次活动累计功勋 */
    public int curTotalExploit;
    /** 本次活动最高连胜 */
    public int curMaxContinueWin;

    private Player player;

    public CampBattleData(Player player)
    {
        this.player = player;

        battleCardList = new CopyOnWriteArrayList<>();
//        matchList = new CopyOnWriteArrayList<>();
        battleList = new CopyOnWriteArrayList<>();
    }

    @Override
    public void init() {

    }

    @Override
    public void checkInit()
    {

    }

    @Override
    public void reset()
    {

    }

    @Override
    public void checkReset() {

    }

    @Override
    public void writeTo(ByteBuffer buffer)
    {
        buffer.writeUTF(activityIndex);
        buffer.writeShort(applyCount);
        buffer.writeByte(reviveCount);
        buffer.writeInt(totalWinCount);
        buffer.writeInt(totalBattleCount);
        buffer.writeShort(maxContinueWin);
        buffer.writeInt(totalExploit);
        buffer.writeInt(maxRank);
        buffer.writeInt(curTotalExploit);
        buffer.writeShort(curMaxContinueWin);
        buffer.writeBoolean(isGetRewarded);

        int size = battleCardList.size();
        buffer.writeByte(size);
        for(CardDB cardDB : battleCardList)
        {
            cardDB.writeTo(buffer);
        }

        //***************************旧的
//        size = matchList.size();
//        buffer.writeByte(size);
//        for(String objectIndex : matchList)
//        {
//            buffer.writeUTF(objectIndex);
//        }
        //****************************

        //*****************新的,不再需要匹配记录，在活动服就处理了
        buffer.writeByte(0);
        //*****************

        size = battleList.size();
        buffer.writeInt(size);
        for(CampBattleBean campBattleBean : battleList)
        {
            campBattleBean.writeTo(buffer);
        }
    }

    @Override
    public void loadFrom(ByteBuffer buffer)
    {
        this.activityIndex = buffer.readUTF();
        this.applyCount = buffer.readShort();
        this.reviveCount = buffer.readByte();
        this.totalWinCount = buffer.readInt();
        this.totalBattleCount = buffer.readInt();
        this.maxContinueWin = buffer.readShort();
        this.totalExploit = buffer.readInt();
        this.maxRank = buffer.readInt();
        this.curTotalExploit = buffer.readInt();
        this.curMaxContinueWin = buffer.readShort();
        this.isGetRewarded = buffer.readBoolean();

        int size = buffer.readByte();
        CardDB cardDB = null;
        for(int i = 0; i < size; i++)
        {
            cardDB = new CardDB(player);
            cardDB.loadFrom(buffer);
            battleCardList.add(cardDB);
        }

        //**************************旧的
//        size = buffer.readByte();
//        for(int i = 0; i < size; i++)
//        {
//            matchList.add(buffer.readUTF());
//        }
        //**************************

        //*************************新的,不再需要匹配记录
        size = buffer.readByte();
        for(int i = 0; i < size; i++)
        {
            buffer.readUTF();
        }
        //*************************

        size = buffer.readInt();
        CampBattleBean campBattleBean = null;
        for(int i = 0; i < size; i++)
        {
            campBattleBean = new CampBattleBean();
            campBattleBean.loadFrom(buffer);
            battleList.add(campBattleBean);

            if(campBattleBean.win)
                curWinCount++;
        }

        curBattleCount = battleList.size();
    }

    public void clearAll()
    {
        isGetRewarded = false;
        curTotalExploit = 0;
        curMaxContinueWin = 0;
        curWinCount = 0;
        curBattleCount = 0;
        battleList.clear();
        activityIndex = "";
        applyCount = 0;
        reviveCount = -1;
        totalBattleCount = 0;
        totalWinCount = 0;
        totalExploit = 0;
        maxContinueWin = 0;
        maxRank = 0;
        battleCardList.clear();
//        matchList.clear();
    }

    public void clearReward()
    {
        isGetRewarded = false;
        curTotalExploit = 0;
        curMaxContinueWin = 0;
        curWinCount = 0;
        curBattleCount = 0;
        battleList.clear();
    }

    public void clearApplyData()
    {
        activityIndex = "";
        applyCount = 0;
        reviveCount = -1;
    }

    /**
     * 是否有可领取的奖励
     * @return
     */
    public boolean isHaveRewardForGet()
    {
        return !isGetRewarded && curMaxContinueWin > 0 && curTotalExploit > 0;
    }


    public void win(MatchBaseInfo target, int addExploit, int masterHPRate, int armyHPRate)
    {
        addTotalExploit(addExploit);

        CampBattleBean campBattleBean = new CampBattleBean();
        campBattleBean.win = true;
        if(target != null)
        {
            campBattleBean.targetIndex = target.getObjectIndex();
            campBattleBean.targetName = target.getName();
            campBattleBean.targetAvatar = target.getAvatar();
            campBattleBean.targetFC = target.getFc();
            campBattleBean.targetServerId = target.getServerId();
        }

        campBattleBean.addParam(CampBattleBean.GET_EXPLOIT, addExploit);
        if(masterHPRate < 0 && armyHPRate < 0)
        {
            if(!battleList.isEmpty())
            {
                CampBattleBean last = battleList.get(battleList.size()-1);

                campBattleBean.addParam(CampBattleBean.MASTER_HP_RATE, last.getParam(CampBattleBean.MASTER_HP_RATE));
                campBattleBean.addParam(CampBattleBean.ARMY_HP_RATE, last.getParam(CampBattleBean.ARMY_HP_RATE));
            }
        }
        else
        {
            campBattleBean.addParam(CampBattleBean.MASTER_HP_RATE, masterHPRate);
            campBattleBean.addParam(CampBattleBean.ARMY_HP_RATE, armyHPRate);
        }

        battleList.add(campBattleBean);

        totalBattleCount++;
        totalWinCount++;
        curBattleCount++;
        curWinCount++;

        updateMaxContinueWinCount();
    }

    private void lose(MatchBaseInfo target, int loseType)
    {
        CampBattleBean campBattleBean = new CampBattleBean();
        campBattleBean.win = false;
        if(target != null)
        {
            campBattleBean.targetIndex = target.getObjectIndex();
            campBattleBean.targetName = target.getName();
            campBattleBean.targetAvatar = target.getAvatar();
            campBattleBean.targetFC = target.getFc();
            campBattleBean.targetServerId = target.getServerId();
        }

        campBattleBean.addParam(CampBattleBean.LOSE_TYPE, loseType);
        campBattleBean.addParam(CampBattleBean.REVIVE_CUR_COUNT, reviveCount);

        StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.CAMP_ACTIVITY_APPLY.getCode());
        campBattleBean.addParam(CampBattleBean.REVIVE_MAX_COUNT, stableDataConfig.intValue);

        battleList.add(campBattleBean);

        totalBattleCount++;
        curBattleCount++;
    }

    public boolean revive(MatchBaseInfo target)
    {
        if(reviveCount <= 0)
        {
            reviveCount--;
            lose(target, CampBattleBean.LOSE_TYPE_DEFAULT);
            return false;
        }

        reviveCount--;
        lose(target, CampBattleBean.LOSE_TYPE_REVIVE);
        return true;
    }

    private void addTotalExploit(int value)
    {
        if(value == 0)
            return;

        totalExploit += value;
        curTotalExploit += value;
    }

    public void apply(String activityIndex, int reviveCount, List<CardDB> battleCardList)
    {
//        if(applyCount == 0)
//        {
//            matchList.clear();
//        }

        this.applyCount++;

        this.activityIndex = activityIndex;

        this.reviveCount = reviveCount;

        setBattleCardList(battleCardList);
    }

//    public void addMatch(String targetIndex)
//    {
//        matchList.add(targetIndex);
//
//        if(matchList.size() > 2)
//            matchList.remove(0);
//    }

    public void setBattleCardList(List<CardDB> list)
    {
        battleCardList.clear();

        for(CardDB cardDB : list)
        {
            battleCardList.add(new CardDB(cardDB));
        }
    }

    /**
     * 更新最高连胜
     * @return
     */
    public void updateMaxContinueWinCount()
    {
        StringBuffer sb = new StringBuffer();
        for(CampBattleBean campBattleBean : battleList)
        {
            sb.append(campBattleBean.win?1:0);
        }

        if(sb.length() == 0)
            return;

        String[] array = sb.toString().split("0");

        for(String s : array)
        {
            maxContinueWin = Math.max(maxContinueWin, s.length());
        }
        for(String s : array)
        {
            curMaxContinueWin = Math.max(curMaxContinueWin, s.length());
        }
    }


    /**
     * 本次活动的胜率
     * @return
     */
    public int getCurWinRate()
    {
        if(curBattleCount == 0)
            return 0;

        double rate = (double) curWinCount / curBattleCount * 100;
        return (int) (Math.round(rate));
    }

    /**
     * 累计总胜率
     * @return
     */
    public int getTotalWinRate()
    {
        if(totalBattleCount == 0)
            return 0;

        double rate = (double) totalWinCount / totalBattleCount * 100;
        return (int) (Math.round(rate));
    }


    public void checkReward(String activityIndex, int myCampRank)
    {
        LogUtils.debug("检测活动奖励 -> activityIndex:" + activityIndex + " 我的阵营排名:" + myCampRank);
        if(CoreUtils.isNullOrEmpty(activityIndex) || myCampRank == 0)
            return;

        if(isHaveRewardForGet())
        {
            int rewardExploit = getTotalRewardExploit(myCampRank);
            if(myCampRank > 0 && rewardExploit > 0)
            {
                MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.CAMP_ACTIVITY_REWARD.getCode());
                if(mailConfig != null)
                {
                    MailInfo mailInfo = player.getExtInfo(MailInfo.class);

                    List<GoodsData> list = new ArrayList<>();
                    list.add(new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS_VALUE, ConfigFactory.ASSET_EXPLOIT_KEY, rewardExploit));
                    MailDB mailDB = new MailDB(mailConfig.title, MessageFormat.format(mailConfig.content, rewardExploit), list);
                    mailInfo.addMail(SGCommonProto.E_MAIL_TYPE.MAIL_TYPE_SYSTEM_VALUE, mailDB);

                    LogUtils.debug("邮件发送阵营战奖励 -> " + player.name + " 功勋 -> " + rewardExploit);
                }
                else
                {
                    LogUtils.error("阵营战邮件模板为空 -> " + E_MailModelType.CAMP_ACTIVITY_REWARD.getCode());
                }
                setGetRewarded(true);
            }
        }

        if(!this.activityIndex.equals(activityIndex))
        {
            clearApplyData();
        }
    }

    public int getTotalRewardExploit(int myCampRank)
    {
        if(curTotalExploit == 0)
            return 0;

        int addExploit = (int) (curMaxContinueWin * (curTotalExploit * 0.05));
        addExploit = addExploit > curTotalExploit ? curTotalExploit : addExploit;

        if(myCampRank == 1)
            addExploit += curTotalExploit;
        else if(myCampRank == 2)
            addExploit += curTotalExploit * 0.6;
        else if(myCampRank == 3)
            addExploit += curTotalExploit * 0.4;

        return addExploit;
    }
//    public int getWinCount()
//    {
//        int winCount = 0;
//        for(CampBattleBean campBattleBean : battleList)
//        {
//            if(campBattleBean.win)
//                winCount++;
//        }
//        return winCount;
//    }


    public void setMaxRank(int rank)
    {
        maxRank = rank > maxRank ? rank : maxRank;
    }

    public List<CampBattleBean> getBattleList()
    {
        return battleList;
    }



    public List<CardDB> getBattleCardList() {
        return battleCardList;
    }

//    public List<String> getMatchList() {
//        return matchList;
//    }


    public boolean isGetRewarded() {
        return isGetRewarded;
    }

    public void setGetRewarded(boolean isGetRewarded) {
        this.isGetRewarded = isGetRewarded;
    }
}
